20#include "kernels/Utils.h"
53 if (
input()->element_type() == DataType::FLOAT32 &&
filter()->element_type() == DataType::FLOAT32)
57 else if (
input()->element_type() == DataType::U8 &&
filter()->element_type() == DataType::U8)
61 else if (
input()->element_type() == DataType::S8 &&
filter()->element_type() == DataType::S8)
66 static_cast<size_t>(
filter()->shape().dim(0)));
72 else if (
input()->element_type() == DataType::S16 &&
filter()->element_type() == DataType::S16)
78 throw std::runtime_error(
"luci-intp Conv2D(1) Unsupported type.");
97 const int32_t output_height =
100 const int32_t output_width =
107 filter_width, output_width);
112 tflite::ConvParams
params{};
113 params.padding_values.height = _padding_height;
114 params.padding_values.width = _padding_width;
126 case Activation::NONE:
127 case Activation::RELU:
128 case Activation::RELU6:
129 case Activation::RELU_N1_TO_1:
132 throw std::runtime_error(
"Unsupported fused activation");
138 switch (
input()->element_type())
140 case DataType::FLOAT32:
141 if (
filter()->element_type() == DataType::FLOAT32)
146 throw std::runtime_error(
"luci-intp Conv2D(2) Unsupported type.");
156 static_cast<size_t>(
filter()->shape().dim(0)));
157 evalQuantizedPerChannel();
161 evalQuantizedS8PerChannel();
167 throw std::runtime_error(
"luci-intp Conv2D(3) Unsupported type.");
171void Conv2D::evalFloat()
const
173 float activation_min{};
174 float activation_max{};
177 tflite::ConvParams
params{};
178 params.padding_values.height = _padding_height;
179 params.padding_values.width = _padding_width;
184 params.float_activation_min = activation_min;
185 params.float_activation_max = activation_max;
199void Conv2D::evalQuantized()
const
201 const auto input_scale =
static_cast<double>(
input()->
scale());
203 const auto output_scale =
static_cast<double>(
output()->
scale());
206 int32_t output_multiplier{};
210 int32_t activation_min{};
211 int32_t activation_max{};
214 tflite::ConvParams
params{};
215 params.padding_values.height = _padding_height;
216 params.padding_values.width = _padding_width;
225 params.output_multiplier = output_multiplier;
226 params.output_shift = output_shift;
227 params.quantized_activation_min = activation_min;
228 params.quantized_activation_max = activation_max;
238void Conv2D::evalQuantizedPerChannel()
const
264 int32_t activation_min{};
265 int32_t activation_max{};
275 for (int32_t batch = 0; batch <
batches; ++batch)
311 int32_t
scaled_acc = tflite::MultiplyByQuantizedMultiplier(
324void Conv2D::evalQuantizedS8PerChannel()
const
326 int32_t activation_min{};
327 int32_t activation_max{};
330 tflite::ConvParams
params{};
331 params.padding_values.height = _padding_height;
332 params.padding_values.width = _padding_width;
339 params.weights_offset = 0;
341 params.quantized_activation_min = activation_min;
342 params.quantized_activation_max = activation_max;
350 std::vector<int32_t>
shifts;
352 [](ChannelQuantMultipliers
cm) { return cm.shift; });
356 [](ChannelQuantMultipliers
cm) { return cm.multiplier; });
363 luci_interpreter_pal::ConvPerChannel(
370void Conv2D::evalQuantizedS16()
const
396 int32_t activation_min{};
397 int32_t activation_max{};
407 for (int32_t batch = 0; batch <
batches; ++batch)
442 int32_t
scaled_acc = tflite::MultiplyByQuantizedMultiplier(
const std::vector< Tensor * > & getOutputTensors() const
const Conv2DParams _params
const Conv2DParams & params() const
void resize(const Shape &new_shape)
const Shape & shape() const
const std::vector< int32_t > & zero_points() const
int32_t zero_point() const
const Tensor * input() const
Conv2D(const Tensor *input, const Tensor *filter, const Tensor *bias, Tensor *output, Tensor *scratchpad, const Conv2DParams ¶ms)
void configure() override
const Tensor * bias() const
void execute() const override
const Tensor * filter() const
#define LUCI_INTERPRETER_CHECK(cond)
const luci_interpreter::RuntimeShape output_shape
int32_t computePadding(int32_t stride, int32_t dilation_rate, int32_t in_size, int32_t filter_size, int32_t out_size)
int32_t calcOffset(const Shape &shape, int32_t d0, int32_t d1, int32_t d2, int32_t d3)
std::vector< ChannelQuantMultipliers > quantizeMultipliers(const std::vector< double > &effective_scale)
tflite::RuntimeShape getTensorShape(const Tensor *tensor)
void calculateActivationRange(Activation activation, T *activation_min, T *activation_max)
void calculateActivationRangeQuantized(Activation activation, const Tensor *output, int32_t *activation_min, int32_t *activation_max)
void quantizeMultiplier(double double_multiplier, int32_t *quantized_multiplier, int *shift)
int32_t computeOutputSize(Padding padding, int32_t image_size, int32_t filter_size, int32_t stride, int32_t dilation_rate=1)
std::vector< double > getQuantizedConvolutionMultiplers(float input_scale, const std::vector< float > &filter_scale, float output_scale)
T must_cast(loco::Node *node)
int32_t dilation_width_factor
int32_t dilation_height_factor