19#include "kernels/Utils.h"
21#include "kernels/BinaryOpCommon.h"
32void evalQuantized(
const circle::Tensor *input1,
const circle::Tensor *input2,
33 const circle::Tensor *output,
const circle::MulOptions *options,
36 assert(
type == DataType::S16
or type == DataType::S8 &&
"Wrong Type");
47 assert(
need_broadcast ==
false &&
"Broadcast for INT8 and INT16 not supported now");
49 params.input1_offset = -Tensor::zero_point(input1);
50 params.input2_offset = -Tensor::zero_point(input2);
51 params.output_offset = Tensor::zero_point(output);
53 const auto input1_scale =
static_cast<double>(Tensor::scale(input1));
54 const auto input2_scale =
static_cast<double>(Tensor::scale(input2));
55 const auto output_scale =
static_cast<double>(Tensor::scale(output));
62 output, ¶ms.quantized_activation_min,
63 ¶ms.quantized_activation_max);
64 if (
type == DataType::S8)
66 luci_interpreter_pal::Mul(
68 kernels::getTensorData<int8_t>(runtime_graph->getDataByTensor(input1)),
69 kernels::getTensorData<int8_t>(runtime_graph->getDataByTensor(input2)),
70 kernels::getTensorData<int8_t>(runtime_graph->getDataByTensor(output)));
74 luci_interpreter_pal::Mul(
76 kernels::getTensorData<int16_t>(runtime_graph->getDataByTensor(input1)),
77 kernels::getTensorData<int16_t>(runtime_graph->getDataByTensor(input2)),
78 kernels::getTensorData<int16_t>(runtime_graph->getDataByTensor(output)));
90 Tensor::element_type(kernel.
input2()));
92 Tensor::element_type(kernel.
input2()));
94 if (Tensor::element_type(kernel.
input1()) == DataType::S16)
97 Tensor::zero_points(kernel.
input2()).size() == 1);
99 Tensor::zero_point(kernel.
input2()) == 0 &&
100 Tensor::zero_point(kernel.
output()) == 0);
109 const auto *options =
cur_op->builtin_options_as_MulOptions();
120 const auto type = Tensor::element_type(kernel.
input1());
124 case DataType::FLOAT32:
126 auto tiso_func = luci_interpreter_pal::Mul<float>;
146 auto tiso_func = luci_interpreter_pal::Mul<int64_t>;
165 auto tiso_func = luci_interpreter_pal::Mul<int32_t>;
186 evalQuantized(kernel.
input1(), kernel.
input2(), kernel.
output(), options, runtime_graph,
192 assert(
false &&
"Unsupported type.");
bool is_inplace_op(const circle::Operator *op)
const circle::Tensor * output() const
const circle::Tensor * input2() const
const circle::Tensor * input1() const
#define LUCI_INTERPRETER_CHECK(cond)
const luci_interpreter::RuntimeShape output_shape
DataType
"scalar" value type
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)
luci_interpreter::RuntimeShape getTensorRuntimeShape(const circle::Tensor *circle_tensor, BaseRuntimeGraph *runtime_graph)
bool ProcessBroadcastShapes(const luci_interpreter::RuntimeShape &shape0, const luci_interpreter::RuntimeShape &shape1, luci_interpreter_pal::ArithmeticParams *params)
RuntimeGraph BaseRuntimeGraph
void configure_kernel_CircleMul(const circle::Operator *cur_op, BaseRuntimeGraph *runtime_graph)
void execute_kernel_CircleMul(const circle::Operator *cur_op, BaseRuntimeGraph *runtime_graph)
T must_cast(loco::Node *node)
FusedActFunc luci_actfunc(const circle::ActivationFunctionType type)