2 * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "OperationUtils.h"
18 #include "QuantizeLayer.h"
20 #include <cker/operation/Dequantize.h>
21 #include <cker/operation/Erf.h>
22 #include <cker/operation/Exp.h>
23 #include <cker/operation/LogicalNot.h>
24 #include <cker/operation/Quantize.h>
25 #include <cker/operation/Round.h>
35 template <typename InputT, typename OutputT>
36 void affineQuantize(const IPortableTensor *input, IPortableTensor *output)
38 nnfw::cker::Quantize(getShape(input), getBuffer<InputT>(input), getShape(output),
39 getBuffer<OutputT>(output), output->data_scale(), output->data_zero_point());
42 void QuantizeLayer::configure(const IPortableTensor *input, IPortableTensor *output)
44 assert(input != nullptr);
45 assert(output != nullptr);
50 if ((_input->data_type() == OperandType::FLOAT32))
54 else if (((input->data_type() == OperandType::QUANT_UINT8_ASYMM) &&
55 (output->data_type() == OperandType::QUANT_INT8_ASYMM)) ||
56 ((input->data_type() == OperandType::QUANT_INT8_ASYMM) &&
57 (output->data_type() == OperandType::QUANT_UINT8_ASYMM)))
59 const double effective_output_scale =
60 static_cast<double>(input->data_scale()) / static_cast<double>(output->data_scale());
61 QuantizeMultiplier(effective_output_scale, &_output_multiplier, &_output_shift);
65 throw std::runtime_error{"Quantize: Unsupported data type"};
69 void QuantizeLayer::run()
71 if ((_input->data_type() == OperandType::FLOAT32))
73 affineQuantize<float, uint8_t>(_input, _output);
75 else if ((_input->data_type() == OperandType::QUANT_UINT8_ASYMM) &&
76 (_output->data_type() == OperandType::QUANT_INT8_ASYMM))
78 nnfw::cker::Requantize<uint8_t, int8_t>(
79 getBuffer<uint8_t>(_input), MatchingFlatSize(getShape(_input), getShape(_output)),
80 _output_multiplier, _output_shift, _input->data_zero_point(), _output->data_zero_point(),
81 getBuffer<int8_t>(_output));
83 else if ((_input->data_type() == OperandType::QUANT_INT8_ASYMM) &&
84 (_output->data_type() == OperandType::QUANT_UINT8_ASYMM))
86 nnfw::cker::Requantize<int8_t, uint8_t>(
87 getBuffer<int8_t>(_input), MatchingFlatSize(getShape(_input), getShape(_output)),
88 _output_multiplier, _output_shift, _input->data_zero_point(), _output->data_zero_point(),
89 getBuffer<uint8_t>(_output));
93 throw std::runtime_error{"Quantize: Unsupported data type"};
99 } // namespace backend